iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
Modern Web

Go 快 Go 高效: 從基礎語法到現代Web應用開發系列 第 27

【Day27】隱私守護專家 I | 環境變數建立

  • 分享至 

  • xImage
  •  

什麼是環境變數?

環境變數是一組鍵值對,用來在作業系統層級儲存配置信息。這些變數可以被運行在該系統上的所有應用程式所訪問。常見的環境變數包括:
PATH:系統尋找可執行檔的路徑。
HOMEUSERPROFILE:用戶的主目錄。
自定義變數:如 DB_HOSTAPI_KEY 等,用於應用程式的特定配置。

我們的環境變數都會以大寫來做命名。

以下內容皆是在 Mac 上做操作


設定環境變數

  • 設置臨時的環境變數
export DB_HOST="localhost"

小提示:這個設置只會在所使用的終端機環境內生效
如果不是在被使用的終端機下運行程式,則不會生效。

  • 設置全域的環境變數(永久)

編輯 shell 配置文件(如 ~/.bashrc, ~/.zshrc 等)。
在文本編輯器(如 VSCode, Vim)中開啟上面的配置文件。

# 在 VSCode 中打開
code . ~/.zshrc

# 在 Vim 中打開
vim ~/.zshrc

然後輸入下面配置內容。

export VARIABLE_NAME="value"

保存配置文件後,記得在重回 terminal 中執行下面內容來重新加載配置內容。

# bashrc
source ~/.bashrc

# zshrc
source ~/.zshrc

在 Go 程式中使用環境變數

  • 讀取環境變數
package main

import (
    "fmt"
    "os"
)

func main() {
    dbHost := os.Getenv("DB_HOST")
    if dbHost == "" {
        fmt.Println("DB_HOST is not set")
    } else {
        fmt.Println("DB_HOST:", dbHost)
    }
}
</* Output: */>
DB_HOST:localhost

使用 os.Getenv 函數來讀取環境變數的值。

  • 設置環境變數
package main

import (
    "fmt"
    "os"
)

func main() {
    err := os.Setenv("DB_HOST", "localhost")
    if err != nil {
        fmt.Println("Error setting environment variable:", err)
        return
    }

    dbHost := os.Getenv("DB_HOST")
    fmt.Println("DB_HOST:", dbHost)
}
</* Output: */>
DB_HOST:localhost

使用 os.Setenv 函數來設置環境變數的值。


使用 .env 文件管理環境變數

GoLand

  • 點擊右上方的 Edit Configuration 來進行當前專案的運行/測試配置。
    https://ithelp.ithome.com.tw/upload/images/20241005/20161850040gcvtGq6.png

  • 找到我們 Environment 的位置後點擊旁邊的按鈕,然後從左上方的 + 來去建立我們的 Key-Value,記得儲存後就能直接使用。
    https://ithelp.ithome.com.tw/upload/images/20241005/20161850y1OBiDQVF3.png

Other

我們在我們的專案目錄下,在額外新增一個 .env 的檔案。

  • 加入下面內容做測試
DB_HOST=localhost

小提示:我們名稱都記得用大寫來做表示,然後 = 兩側不要加空格。

  • 匯入我們要用的依賴包
go get -u github.com/joho/godotenv
  • 測試我們的環境變數
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/joho/godotenv"
)

func init() {
	if err := godotenv.Load("./.env"); err != nil {
		log.Fatalf("Error loading .env file: %s", err)
	}
}

func main() {

	dbHost := os.Getenv("DB_HOST")
	if dbHost == "" {
		fmt.Println("DB_HOST is not set")
	} else {
		fmt.Println("DB_HOST:", dbHost)
	}
}
</* Output: */>
DB_HOST=localhost

godotenv.Load("./.env"):會去嘗試載入我當前目錄下的.env文件,但如果你習慣跟我一樣把 main.go 包在 cmd 目錄裡的,記得換成 godotenv.Load("../.env"),來去尋找上層的 .env 檔案。


實踐演示

這部分以 資料庫的連接為例

./
├── cmd/
│   └── main.go
├── database/
│   ├── model/
│   │   └── userProfile.go
│   └── database.go
├── .env
├── go.mod
└── go.sum

總共:4 個目錄,5 個檔案
  • userProfile.go

我們在 database/model/userProfile.go 下加入我們資料庫的數據表

package model

type UserProfile struct {
	ID       int    `json:"id" gorm:"primary_key"`
	Username string `json:"username"`
	Email    string `json:"email"`
	Password string `json:"password"`
	Role     string `json:"role"`
}
  • database.go

我們在 database/database.go 下加入我們資料庫的操作

package database

import (
	"fmt"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
	"log"
	"os"
)

type Database struct {
	Context *gorm.DB
}

var DB *Database

func ConnectDB() {
	var dsn string = fmt.Sprintf(
		"host=%s user=%s dbname=%s port=%s sslmode=%s TimeZone=Asia/Taipei",
		os.Getenv("DB_HOST"), os.Getenv("DB_USER"), os.Getenv("DB_NAME"), os.Getenv("DB_PORT"), os.Getenv("DB_WITH_SSL"))

	var db *gorm.DB
	var err error

	db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})

	if err != nil {
		panic("failed to connect database: " + err.Error())
	} else {
		fmt.Println("Database connected success")
	}
    
    db.AutoMigrate(&model.UserProfile{})

	DB = &Database{
		Context: db,
	}
}

func CloseDB() {
	if DB == nil {
		log.Println("Database not initialized, nothing to close.")
		return
	}

	sqlDB, err := DB.Context.DB()
	if err != nil {
		log.Printf("Error getting sql.DB: %v", err)
		return
	}

	if err := sqlDB.Close(); err != nil {
		log.Printf("Error closing database: %v", err)
	} else {
		fmt.Println("Database connection closed successfully")
	}
}
  • .env

我們在 .env 檔案下配置我們的環境變數值

DB_HOST=localhost
DB_USER=****
DB_NAME=****
DB_PORT=5432
DB_WITH_SSL=disable
  • main.go
package main

import (
	"demo/database"
	"github.com/joho/godotenv"
	"log"
)

func init() {
	if err := godotenv.Load("./.env"); err != nil {
		log.Fatalf("Error loading .env file: %s", err)
	}
}

func main() {
	database.ConnectDB()
	defer database.CloseDB()
}
</* Output: */>
2024/10/05 18:44:16 Database connected success
Database connection closed successfully

總結

環境變數提供了一種靈活且安全的方式來管理應用程式的配置。通過本文的教學,您應該已經了解了如何系統上設置環境變數,以及如何在 Go 程式中讀取和使用這些變數。


上一篇
【Day26】即時串流通信服務 III | 測試 gRPC 方法 × Apifox/Postman
系列文
Go 快 Go 高效: 從基礎語法到現代Web應用開發27
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言